import { _decorator, Component, find, ModelRenderer, Node, PlaneCollider, ProgressBar } from 'cc';
import { AnimationControl } from '../Control/AnimationControl';
import { RoleDt } from '../../../FrameWork3.8.6/FrameWork/Common/CommonInterface';
import { ShiBingLayer } from '../ModuleLayer/ShiBingLayer';
import { ModuleMgr } from '../../../FrameWork3.8.6/FrameWork/Module/ModuleMgr';
import { PlayerLayer } from '../ModuleLayer/PlayerLayer';
import type{ ShiBingBase } from './ShiBingBase';
const { ccclass, property } = _decorator;

@ccclass('CharacterBase')
//这是基类，不管是玩家还是敌人boss都需要继承这个
export class CharacterBase extends Component {
    protected _roleDt:RoleDt=null;
    get roleDt(){
        return this._roleDt;
    }
    protected _animationCtrl:AnimationControl=null;
    //血条UI
    protected _Hpbar:ProgressBar=null;

    //总共血条数值
    protected _totalHp:number=0;
    //当前血条数值
    protected _curHp:number=0;
    //士兵层PlayerLayer
    protected _shiBingLayer:ShiBingLayer=null;

    //玩家层
    protected _playerLayer:PlayerLayer=null;

    //当前范围是否有敌人
    protected _arrEnemy:Node[]=[];

    //区分是玩家还是敌人
    protected _QufenDir:number=0;
    get QufenDir(){
        return this._QufenDir;
    }


    onInit(roleDt:RoleDt,qufenDir:number){
        this._QufenDir=qufenDir;

        this._roleDt=roleDt;
        this._animationCtrl=this.node.addComponent(AnimationControl);

        //初始化血条UI
        this._Hpbar=this.node.getChildByName("_Hp").getComponent(ProgressBar);
        //初始化血条数值
        this._totalHp=roleDt.hp;
        this._curHp=this._totalHp;
        //初始化士兵层
        this._shiBingLayer=ModuleMgr.instance.getModule<ShiBingLayer>("ShiBingLayer");
        //初始化玩家层
        this._playerLayer=ModuleMgr.instance.getModule<PlayerLayer>("_PlayerLayer");
        this.lateInit.apply(this,arguments);
    }

    //供派生类重写的方法
    lateInit(...rest:any[]){

    }
    //士兵有四种状态，走路，攻击，受伤，死亡
    walk(){
        this._animationCtrl.playState(this._roleDt.prefabName+"Walk");
    }

    attack(target:Node){
        //console.log(this.roleDt.prefabName+"攻击")
        this._animationCtrl.playState(this._roleDt.prefabName+"Attack");
        //这里应该有自己的帧动画，在攻击一瞬间对敌人进行判定是否击中

        let CharacterBaseTs=target.getComponent(CharacterBase);
        if(CharacterBaseTs){
            CharacterBaseTs.hurt(this.roleDt.ack);
        }
        else{
           (target.getComponent("ShiBingBase") as ShiBingBase).hurt(this.roleDt.ack);
        }
    }

    hurt(damage:number){
        //先播放受伤动画
        this._animationCtrl.playState(this._roleDt.prefabName+"Hurt");
        //血条只有在玩家受伤时才会出现0.5秒，展示血条扣血
        this._curHp-=damage;
        if(this._curHp>0){
            this._Hpbar.progress=this._curHp/this._totalHp;
            this._Hpbar.node.active=true;
            this.scheduleOnce(()=>{
                this._Hpbar.node.active=false;
            },0.5)
            return;
        }
        //当兵种血条<=0时，触发死亡
        this.death();
    }

    death(){
        this._animationCtrl.playState(this._roleDt.prefabName+"Death");
        //播放死亡音乐
        //呼叫ShiBingLayer的回收方法
        if(this.roleDt.camp=="玩家"){
            //先播放死亡动画

            //再回收并且暂停时间
            this._playerLayer.removePlayer();
            return;
        }
        this._shiBingLayer.deleteBoss(this);
        
    }

    //搜寻当前范围有没有敌人
    searchEnemy(){
        if(this._roleDt.camp=="玩家"){
            let endPosX=this.node.position.x+50*this._roleDt.ackRange;
            this._arrEnemy=this._shiBingLayer.getCamp(this.node.position.x,endPosX,this._roleDt.camp);
        }
        else{
            let endPosX=this.node.position.x+(-50)*this._roleDt.ackRange;
            this._arrEnemy=this._shiBingLayer.getCamp(endPosX,this.node.position.x,this._roleDt.camp);

        }
        
        
    }

    //获取敌方阵营中距离自己最近的一个单位
    getNearestCamp(){
        let nearEnemy:Node=null;
        let dis:number=10000;//nearEnemy距离这个节点的距离
        for(let enemy of this._arrEnemy){
            let distance=Math.abs(enemy.position.x-this.node.position.x);
            if(distance<dis){
                dis=distance;
                nearEnemy=enemy;
            }
        }
        return nearEnemy;
    }
}


